﻿using FSM.IBll;
using FSM.IDal;
using FSM.Model;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Util.Extensions;
using Util.Helper;

namespace FSM.Bll
{
    public class SysUserBll : ISysUserBll
    {
        #region 模块

        /// <summary>
        /// 用户数据处理类
        /// </summary>
        private readonly ISysUserDal userDal;

        #endregion

        #region 构造函数

        public SysUserBll(ISysUserDal user_dal)
        {
            this.userDal = user_dal;
        }

        #endregion

        #region 查询

        /// <summary>
        /// 获得单个用户信息
        /// </summary>
        /// <param name="user_no">用户编号</param>
        /// <returns></returns>
        public sys_user Get(string user_no)
        {
            return userDal.GetById(user_no);
        }

        /// <summary>
        /// 列出用户信息
        /// </summary>
        /// <param name="user_no">用户账号</param>
        /// <param name="user_name">用户名称</param>
        /// <param name="page">页码</param>
        /// <param name="page_size">每页显示的条数</param>
        /// <returns>
        /// 用户记录和总记录数
        /// </returns>
        public Tuple<List<sys_user>, int> List(string user_no, string user_name, int page, int page_size)
        {
            ISugarQueryable<sys_user> queryable = userDal.CreateQueryable();
            queryable = queryable.WhereIF(!string.IsNullOrEmpty(user_no), p => p.user_name.Contains(user_no));
            queryable = queryable.WhereIF(!string.IsNullOrEmpty(user_name), p => p.user_name.Contains(user_name));
            PageModel pm = new PageModel()
            {
                PageIndex = page,
                PageSize = page_size
            };
            Tuple<List<sys_user>,int> result = userDal.GetPageListAndTotal(queryable, pm);
            return result;
        }

        #endregion

        #region 提交

        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="model">实体</param>
        /// <returns></returns>
        public bool Insert(sys_user model)
        {
            model.key = RandomHelper.RandomCode(10);
            model.password = (model.password ?? "zb001".ToMD5String()).ToMD5String(model.key);
            model.create_date = DateTime.Now;
            return userDal.Insert(model);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="model">实体</param>
        /// <returns></returns>
        public bool Update(sys_user model)
        {
            model.edit_date = DateTime.Now;
            userDal.BeginTran();
            try
            {
                bool success = userDal.UpdateExcludeColumns(model, "key", "password", "creater", "create_date") == 1;
                if (success)
                {
                    userDal.CommitTran();
                    return true;
                }
                else
                {
                    throw new Exception("更新失败");
                }
            }
            catch (Exception)
            {
                userDal.RollbackTran();
                throw;
            }
        }

        /// <summary>
        /// 更新密码
        /// </summary>
        /// <param name="user_no">用户编号</param>
        /// <param name="old_password">旧密码</param>
        /// <param name="new_password">新密码</param>
        /// <returns></returns>
        public bool UpdatePassword(string user_no, string old_password, string new_password)
        {
            user_no.ValidEmptyThrowException("用户编号");
            old_password.ValidEmptyThrowException("原密码");
            new_password.ValidEmptyThrowException("新密码");
            if(old_password == new_password)
            {
                throw new Exception("原密码不能和新密码一致");
            }
            sys_user model = Get(user_no);
            if (model == null) throw new Exception("用户不存在");
            string pwdOld = old_password.ToMD5String(model.key);
            if (pwdOld != model.password)
            {
                throw new Exception("原密码错误");
            }
            model.key = RandomHelper.RandomCode(10);
            model.password = new_password.ToMD5String(model.key);
            userDal.BeginTran();
            try
            {
                model.editer = user_no;
                model.edit_date = DateTime.Now;
                bool success = userDal.UpdateIncludeColumns(model, "key", "password", "editer", "edit_date") == 1;
                if (success)
                {
                    userDal.CommitTran();
                    return true;
                }
                else
                {
                    throw new Exception("更新失败");
                }
            }
            catch (Exception)
            {
                userDal.RollbackTran();
                throw;
            }
        }

        /// <summary>
        /// 还原密码
        /// </summary>
        /// <param name="user_no">用户编号</param>
        /// <param name="oper">操作人员</param>
        /// <returns></returns>
        public bool ResetPassword(string oper, string user_no)
        {
            user_no.ValidEmptyThrowException("用户编号");
            oper.ValidEmptyThrowException("操作人员");
            if (user_no == oper)
            {
                throw new Exception("不能还原当前操作人员的密码");
            }
            sys_user model = Get(user_no);
            if (model == null) throw new Exception("用户不存在");
            model.editer = oper;
            model.edit_date = DateTime.Now;
            model.key = RandomHelper.RandomCode(10);
            model.password = "zb001".ToMD5String().ToMD5String(model.key);
            userDal.BeginTran();
            try
            {
                model.editer = user_no;
                model.edit_date = DateTime.Now;
                bool success = userDal.UpdateIncludeColumns(model, "key", "password", "editer", "edit_date") == 1;
                if (success)
                {
                    userDal.CommitTran();
                    return true;
                }
                else
                {
                    throw new Exception("还原失败");
                }
            }
            catch (Exception)
            {
                userDal.RollbackTran();
                throw;
            }
        }

        /// <summary>
        /// 更新用户头像
        /// </summary>
        /// <param name="oper">操作人员</param>
        /// <param name="user_no">用户编号</param>
        /// <param name="avatar">头像文件</param>
        /// <returns></returns>
        public bool UpdateAvatar(string oper, string user_no, string avatar)
        {
            sys_user user = new sys_user()
            {
                user_no = user_no,
                editer = oper,
                edit_date = DateTime.Now,
                avatar = avatar
            };
            userDal.BeginTran();
            try
            {
                bool success = userDal.UpdateIncludeColumns(user, "avatar", "editer", "edit_date") == 1;
                if (success)
                {
                    userDal.CommitTran();
                    return true;
                }
                else
                {
                    throw new Exception("修改头像失败");
                }
            }
            catch (Exception)
            {
                userDal.RollbackTran();
                throw;
            }
        }

        /// <summary>
        /// 更新用户编号删除指定用户
        /// </summary>
        /// <param name="user_no">用户编号</param>
        /// <returns></returns>
        public bool Delete(string oper, string user_nos)
        {
            userDal.BeginTran();
            try
            {
                user_nos.ValidEmptyThrowException("用户编号");
                string[] userNoArr = user_nos.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                if (userNoArr.Count(p => p.ToLower() == oper.ToLower()) > 0)
                {
                    throw new Exception("不能删除当前操作人员");
                }
                foreach(string userNo in userNoArr)
                {
                    if (!userDal.Delete(userNo))
                    {
                        throw new Exception($"删除用户{userNo}失败");
                    }
                }
                userDal.CommitTran();
                return true;
            }
            catch (Exception)
            {
                userDal.RollbackTran();
                throw;
            }
        }

        #endregion

        #region 扩展方法

        /// <summary>
        /// 登录验证
        /// </summary>
        /// <param name="user_no">用户编号</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        public bool ValidLogin(string user_no, string password)
        {
            sys_user user = Get(user_no);
            if (user == null) throw new Exception("用户不存在");
            string pwd = password.ToMD5String(user.key);
            if (user.password != pwd)
            {
                throw new Exception("用户名或密码错误");
            }
            return true;
        }

        #endregion
    }
}
